package net.topicopedia.servlets.topics;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.labs.repackaged.org.json.JSONArray;
import com.google.appengine.labs.repackaged.org.json.JSONException;
import com.google.appengine.labs.repackaged.org.json.JSONObject;

@SuppressWarnings("serial")
public class CreateTopicServlet extends HttpServlet {
	
	@SuppressWarnings("null")
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
		      throws IOException {
		    System.out.println("Creating new todo ");
		    
		    resp.addHeader("Access-Control-Allow-Origin", "*");
		    
		    String jsonString = req.getParameter("json");
		    
		    JSONObject jsonObject = null;
			try {
				jsonObject = new JSONObject(jsonString);
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
			
			Key topicKey;
			Entity topic = null;
			
			Boolean addToCategory = false;
			
			Long uuid = null;
			String uuidString = "";
			try {
				uuidString = jsonObject.get("uuid")+"";
			} catch (JSONException e2) {
			}
			if ( uuidString.equalsIgnoreCase("") || uuidString.equalsIgnoreCase("null"))
			{
				uuid = null;
			} else {
				uuid = (Long) Long.parseLong(uuidString);
			}
			
			if ( uuid != null )
			{
				topicKey = KeyFactory.createKey("Topic", uuid ) ;
				if ( topicKey != null )
				{
					try {
						topic = datastore.get(topicKey);
					} catch (EntityNotFoundException e) {
					}
				}
			}
			
			String storedTagsString = "";
			JSONArray storedTagsList = null;
			
			if ( topic == null )
			{
				topic = new Entity("Topic");
				addToCategory = true;
			} else {
				storedTagsString = ( (Text) topic.getProperty("tags") ).getValue();
				try {
					storedTagsList = new JSONArray( storedTagsString );
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			String topicTitle = null;
			String topicDescriptor = null;
			try {
				topicTitle = (String) jsonObject.get("title");
				topic.setProperty("title", topicTitle );
			} catch (JSONException e) {
				e.printStackTrace();
			}
			try {
				topic.setProperty("category", jsonObject.get("category") );
			} catch (JSONException e) {
				e.printStackTrace();
			}
			try {
				topicDescriptor = (String) jsonObject.get("descriptor");
				topic.setProperty("descriptor", topicDescriptor );
			} catch (JSONException e) {
				e.printStackTrace();
			}
			JSONArray tagsToStore = null;
			if ( addToCategory )
			{
				try {
					tagsToStore = (JSONArray) jsonObject.get("tags");
					topic.setProperty("tags", new Text ( tagsToStore.toString() ) );
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
				
			try {
				topic.setProperty("links", new Text ( jsonObject.get("links").toString() ) );
			} catch (JSONException e) {
				e.printStackTrace();
			}

			try { 
				topic.setProperty("items", new Text ( jsonObject.get("items").toString() ) );
			} catch (JSONException e) {
				e.printStackTrace();
			}
			
			topicKey = datastore.put( topic );
			
			if ( addToCategory ){
				Key categoryKey;
				try {
					categoryKey = KeyFactory.createKey("Category", Long.parseLong((String) jsonObject.get("category") ));
					try {
						Entity category = datastore.get(categoryKey);
						Long count = (Long) category.getProperty("count");
						if ( count != null )
						{
							count++;
						}
						category.setProperty("count", count);
						categoryKey = datastore.put( category );
						
					} catch (EntityNotFoundException e) {
						e.printStackTrace();
					}
				} catch (NumberFormatException e1) {
					e1.printStackTrace();
				} catch (JSONException e1) {
					e1.printStackTrace();
				}
			}
			
			if (addToCategory )
			{
				for ( int t=0; t< tagsToStore.length(); t++ )
				{
					JSONObject tagObject = null;
					try {
						tagObject = (JSONObject) tagsToStore.get(t);
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if ( tagObject != null )
					{
						Key tagKey = null;
						try {
							tagKey = KeyFactory.createKey("Tag", (Long) Long.parseLong((String) tagObject.get("uuid") ));
						} catch (NumberFormatException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						if ( tagKey != null )
						{
							Entity tag=null;
							try {
								tag = datastore.get(tagKey);
							} catch (EntityNotFoundException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							if ( tag != null )
							{
								Long count = (Long) tag.getProperty("count");
								count++;
								tag.setProperty("count", count);
								
								Text tagTopicsText = (Text) tag.getProperty("topics");
								
								if ( tagTopicsText == null )
								{
									tagTopicsText = new Text ("");
								}
								
								Boolean newTopicsObject = false;
								JSONObject tagTopics = null;
								try {
									if ( tagTopicsText.getValue() == "" )
									{
										tagTopics = new JSONObject();
										newTopicsObject = true;
									} else {
										tagTopics = new JSONObject( tagTopicsText.getValue() );
									}
								} catch (JSONException e) {
									e.printStackTrace();
								}
								if ( tagTopics != null )
								{
									JSONArray tagTopicsArray = null;
									try {
										if ( newTopicsObject )
										{
											tagTopicsArray = new JSONArray();
										} else {
											tagTopicsArray = tagTopics.getJSONArray("topics");
										}
									} catch (JSONException e) {
										e.printStackTrace();
									}
									if ( tagTopicsArray != null )
									{
										String topicRefString = "";
										topicRefString += "{ \"uuid\": \"" + topicKey.getId() + "\", \"title\": \"" + topicTitle + "\", \"descriptor\": \"" + topicDescriptor + "\" }";
										JSONObject tagRefObject = null;
										try {
											tagRefObject = new JSONObject(topicRefString);
										} catch (JSONException e) {
											// TODO Auto-generated catch block
											e.printStackTrace();
										}
										if ( tagRefObject != null )
										{
											tagTopicsArray.put( tagRefObject );
											String tagRefString = "{ \"topics\": " + tagTopicsArray.toString() + "}";
											tag.setProperty("topics", new Text ( tagRefString ) );
											datastore.put(tag);
										}
									}
								}
							}
						}
					}
				}
			}
			
		
			resp.setContentType("text/plain");
			String topicKeyString = topicKey.getId() + "";
			resp.getWriter().println( topicKeyString );
			
	}
	
	protected List<String> convertTagJSONArrayToList ( JSONArray array )
	{
		List<String> list = new ArrayList<String>();
		
		for ( int i=0; i< array.length(); i++ )
		{
			JSONObject tag = null;
			try {
				tag = (JSONObject) array.get(i);
			} catch (JSONException e) {
				e.printStackTrace();
			}
			if ( tag != null )
			{
				String uuid = "";
				try {
					uuid = (String) tag.get("uuid");
				} catch (JSONException e) {
					e.printStackTrace();
				}
				if ( uuid != "")
				{
					list.add( uuid );
				}
			}
		}
		
		return list;
	}
	
	protected JSONArray removeFromJSONArray ( JSONArray source, String uuid )
	{
		JSONArray output = new JSONArray();
		for ( int i=0; i< source.length(); i++ )
		{
			JSONObject storedTopic = null;
			try {
				storedTopic = (JSONObject) source.get(i);
			} catch (JSONException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			if ( storedTopic != null )
			{
				String storedUuid="";
				try {
					storedUuid = storedTopic.getString("uuid");
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if ( storedUuid != "" )
				{
					if ( storedUuid.equals(uuid) == false )
					{
						output.put(storedTopic);
					}
				}
			}
			
		}
		return output;
	}
	
	
	@SuppressWarnings("null")
	protected JSONArray addOrRemoveFromTags ( Key topicKey, JSONArray storedTagsList, JSONArray tagsToStore ) throws JSONException, EntityNotFoundException
	{
		JSONArray output = new JSONArray();
		
		if ( storedTagsList != null || storedTagsList.length() > 0 )
		{
			output = removeFromJSONArray ( storedTagsList, topicKey.getId()+"" );
		}
		
		
		
		return output;
	}

}
 